package cn.htsyb.synergy.orm.jpa.wrapper;

import lombok.Getter;
import lombok.Setter;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.util.Assert;

import jakarta.persistence.Column;
import jakarta.persistence.Table;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.LinkedList;

@Setter
@Getter
/**
 * 实体转原生SQL相关操作
 * 使用方式
 * EntityCoverSqlWrapper<ArchiveDossier> entityCoverSqlWrapper =new EntityCoverSqlWrapper<>(ArchiveDossier.class) ;
 * jdbcTemplate.update("replace INTO " + installTable +" (" + entityCoverSqlWrapper.getPreparedColumn() + ") " +
 *                                 " values (" + entityCoverSqlWrapper.getPreparedParam(archiveDossier) + ") ");
 *
 * @author lakeside hubin_yuan.410@hotmail.com
 * @version V1.0.0
 * @since 1.0
 * @date 2022/5/11
 */
public class EntityCoverSqlWrapper<T> {
    private LinkedHashMap<String, String> fieldColumnMap = new LinkedHashMap<>();
    private LinkedList<String> columnList = new LinkedList<>();
    private LinkedList<String> fieldList = new LinkedList<>();
    private String tableName = "";
    private String preparedColumn = "";
    private String preparedParamPlace = "";

    public EntityCoverSqlWrapper(Class<T> entityCls) {
        Table tableAn = entityCls.getAnnotation(Table.class);
        Assert.notNull(tableAn, "非JPA实体对象");
        if (tableAn != null) {
            tableName = tableAn.name();
        }
        Field[] fieldArr = entityCls.getDeclaredFields();
        for (Field field : fieldArr) {
            Column columnAn = field.getAnnotation(Column.class);
            if (columnAn != null) {
                fieldColumnMap.put(field.getName(), columnAn.name());
                columnList.add(columnAn.name());
                fieldList.add(field.getName());
                appendPreparedColumn(columnAn.name());
                appendPreparedParamPlace();
            }
        }
    }

    public void appendPreparedColumn(String column) {
        preparedColumn += (preparedColumn.length() == 0 ? "" : ",") + column;
    }

    public void appendPreparedParamPlace() {
        preparedParamPlace += (preparedParamPlace.length() == 0 ? "" : ",") + "?";
    }

    public Object[] getPreparedParam(T entity) {
        Object[] paramObjArr = new Object[columnList.size()];
        BeanMap beanMap = BeanMap.create(entity);
        for (int i = 0; i < fieldList.size(); i++) {
            paramObjArr[i] = beanMap.get(fieldList.get(i));
        }

        return paramObjArr;
    }

}
